package com.lanchetech.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.lanchetech.bean.dto.SaplingFeatureDTO;
import com.lanchetech.bean.request.PageReq;
import com.lanchetech.bean.response.BasePageResp;
import com.lanchetech.bean.response.BaseResp;
import com.lanchetech.bean.response.ResultData;
import com.lanchetech.bean.util.PageHelpUtil;
import com.lanchetech.bean.vo.*;
import com.lanchetech.common.enums.*;
import com.lanchetech.common.exception.ResultCodeException;
import com.lanchetech.dao.*;
import com.lanchetech.entity.*;
import com.lanchetech.service.DaoService;
import com.lanchetech.user.service.FarmService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.lanchetech.common.constants.JypConstant.LIMIT_TREE_NUMBER;

@Service
public class FarmServiceImpl implements FarmService {

    @Autowired
    FarmUserMapper farmUserMapper;

    @Autowired
    CowMapper cowMapper;

    @Autowired
    MailboxMapper mailboxMapper;

    @Autowired
    TreeMapper treeMapper;

    @Autowired
    HipoConfigMapper hipoConfigMapper;

    @Autowired
    DaoService daoService;

    @Autowired
    SaplingMapper saplingMapper;

    @Autowired
    FarmProductMapper farmProductMapper;

    @Autowired
    WaterFlowMapper waterFlowMapper;

    @Autowired
    FarmOrderMapper farmOrderMapper;

    @Autowired
    MailboxReadMapper mailboxReadMapper;

    @Autowired
    GrassFlowMapper grassFlowMapper;

    @Autowired
    FarmTaskMapper farmTaskMapper;

    @Autowired
    UserTaskMapper userTaskMapper;

    @Autowired
    UserRelationshipMapper userRelationshipMapper;


    private Calendar getFirstTime(Calendar calendar) {
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        return calendar;
    }

    @Override
    public ResultData<BasePageResp<Mailbox>> getMailBoxPage(PageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<Mailbox> list = mailboxMapper.findAllPage(req);
        //插入或修改阅读时间
        MailboxRead selectMailboxRead = mailboxReadMapper.selectOneByUserIdAndType(user.getId(), req.getType());
        if (selectMailboxRead == null) {
            MailboxRead mailboxRead = MailboxRead.builder()
                    .type(req.getType())
                    .readTime(new Date())
                    .userId(user.getId())
                    .build();
            mailboxReadMapper.insert(mailboxRead);
        } else {
            MailboxRead mailboxRead = MailboxRead.builder()
                    .id(selectMailboxRead.getId())
                    .readTime(new Date())
                    .build();
            mailboxReadMapper.updateByPrimaryKeySelective(mailboxRead);
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<BasePageResp<FarmProduct>> getFarmProductPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        req.setStatus(ToggleEnum.ON.getStatus());
        List<FarmProduct> list = farmProductMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp exchangeFarmProduct(FarmOrder farmOrder) {
        Integer number = farmOrder.getCount();
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        FarmUser selectFarmUser = farmUserMapper.findOneByUserId(user.getId());
        FarmProduct selectFarmProduct = farmProductMapper.selectByPrimaryKey(farmOrder.getFarmProductId());
        BigDecimal needMilk = selectFarmProduct.getMilk().multiply(new BigDecimal(number));
        if (!FarmProductTypeEnum.COW.getType().equals(selectFarmProduct.getType())) {
            return new BaseResp(ResultCode.FAIL);
        }
        if (selectFarmProduct != null && selectFarmProduct.getDeleted().equals(DeletedEnum.DEFAULT.getStatus())) {
            //库存大于需要兑换的数量
            if (selectFarmProduct.getStock() >= number) {
                //当前牛奶大于兑换所需要的牛奶
                if(selectFarmUser.getCurrentMilk().compareTo(needMilk) >= 0 ){
                    FarmProduct farmProduct = FarmProduct.builder()
                            .id(selectFarmProduct.getId())
                            .sales(selectFarmProduct.getSales() + number)
                            .stock(selectFarmProduct.getStock() - number)
                            .updatedAt(new Date())
                            .build();
                    FarmUser farmUser = FarmUser.builder()
                            .id(selectFarmUser.getId())
                            .currentMilk(selectFarmUser.getCurrentMilk().subtract(needMilk))
                            .updatedAt(new Date())
                            .build();
                    farmUserMapper.updateByPrimaryKeySelective(farmUser);
                    farmProductMapper.updateByPrimaryKeySelective(farmProduct);

                    //创建订单
                    FarmOrder createFarmOrder = FarmOrder.builder()
                            .userId(user.getId())
                            .farmProductId(farmOrder.getFarmProductId())
                            .type(FarmProductTypeEnum.COW.getType())
                            .count(number)
                            .milk(needMilk)
                            .userAddressId(farmOrder.getUserAddressId())
                            .logisticsStatus(LogisticsStatusEnum.UNDO.getStatus())
                            .createdAt(new Date())
                            .updatedAt(new Date())
                            .build();
                    farmOrderMapper.insert(createFarmOrder);
                }else {
                    return new BaseResp(ResultCode.EXCHANGE_NEED_MILK_NOT_ENOUGH);
                }

            }else {
                return new BaseResp(ResultCode.EXCHANGE_PRODUCT_NOT_ENOUGH);
            }
        }else {
            return new BaseResp(ResultCode.PRODUCT_DELETED);
        }
        return new BaseResp();
    }

    @Override
    public BaseResp exchangeTreeProduct(FarmOrder farmOrder) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Tree selectTree = treeMapper.selectByPrimaryKey(farmOrder.getTreeId());
        Sapling selectSapling = saplingMapper.selectByPrimaryKey(selectTree.getSaplingId());
        FarmProduct selectFarmProduct = farmProductMapper.selectByPrimaryKey(selectSapling.getFarmProductId());
        //不是当前用户的树
        if (!selectTree.getUserId().equals(user.getId())) {
            return new BaseResp(ResultCode.FAIL);
        }
        //树是否为已收获状态
        if (selectTree.getStatus().equals(TreeStatusEnum.HARVEST.getStatus())) {
            //兑换商品是否足够
            if (selectFarmProduct.getStock() > 0) {
                Tree tree = Tree.builder()
                        .id(selectTree.getId())
                        .status(TreeStatusEnum.HARVEST.getStatus())
                        .updatedAt(new Date())
                        .isExchange(TreeIsExchangeTypeEnum.IS_EXCHANGE.getType())
                        .build();
                FarmProduct farmProduct = FarmProduct.builder()
                        .id(selectFarmProduct.getId())
                        .sales(selectFarmProduct.getSales() + farmOrder.getCount())
                        .stock(selectFarmProduct.getStock() - farmOrder.getCount())
                        .updatedAt(new Date())
                        .build();
                farmProductMapper.updateByPrimaryKeySelective(farmProduct);
                //创建订单
                FarmOrder createFarmOrder = FarmOrder.builder()
                        .userId(user.getId())
                        .farmProductId(selectFarmProduct.getId())
                        .type(FarmProductTypeEnum.TREE.getType())
                        .treeId(farmOrder.getTreeId())
                        .count(1)
                        .milk(BigDecimal.ZERO)
                        .userAddressId(farmOrder.getUserAddressId())
                        .logisticsStatus(LogisticsStatusEnum.UNDO.getStatus())
                        .deleted(DeletedEnum.DEFAULT.getStatus())
                        .createdAt(new Date())
                        .updatedAt(new Date())
                        .build();
                farmOrderMapper.insert(createFarmOrder);
                treeMapper.updateByPrimaryKeySelective(tree);
                //当前树为选中状态
                if(ToggleEnum.ON.getStatus().equals(selectTree.getIsActive())){
                    //设置当前用户的所有果树未选中
                    treeMapper.updateIsActiveByUserId(ToggleEnum.OFF.getStatus(), user.getId());
                    //设置最近创建的树为选中
                    Tree findTree = treeMapper.findOneByUserIdAndIsExchange(user.getId(), TreeIsExchangeTypeEnum.NOT_EXCHANGE.getType());
                    if (findTree != null) {
                        treeMapper.updateIsActiveByIdAndUserId(ToggleEnum.ON.getStatus(), findTree.getId(), user.getId());
                    }
                }
            }else {
                return new BaseResp(ResultCode.EXCHANGE_PRODUCT_NOT_ENOUGH);
            }
        }else {
            return new BaseResp(ResultCode.TREE_NOT_HARVEST);
        }
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<FarmOrderVO>> getMyExchangeProductPage(PageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setUserId(user.getId());
        List<FarmOrderVO> list = farmOrderMapper.getMyExchangeProduct(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, FarmProduct> farmProductMap = daoService.getFarmProductMap(list.stream().map(FarmOrderVO::getFarmProductId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setFarmProductMainImage(farmProductMap.get(item.getFarmProductId()).getMainImage());
                item.setFarmProductName(farmProductMap.get(item.getFarmProductId()).getName());
            });
        }
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<BasePageResp<GrassFlowVO>> getGrassFlowPage(PageReq req) {
        User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setUserId(user.getId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<GrassFlowVO> list = grassFlowMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<BasePageResp<WaterFlowVO>> getWaterFlowPage(PageReq req) {
        User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setUserId(user.getId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<WaterFlowVO> list = waterFlowMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }


    @Override
    public ResultData<FarmUserVO> getCowDetail(User user) {
        FarmUser selectFarmUser = farmUserMapper.findOneByUserId(user.getId());
        Cow selectCow = cowMapper.findOneByUserId(user.getId());

        if (selectFarmUser == null) {

            // 判断是否有人邀请，如果有，则送10kg草料和10kg水能量
            UserRelationship userRelationship = userRelationshipMapper.findOneBySubordinateId(user.getId());
            BigDecimal gift = userRelationship == null ? new BigDecimal(2) : new BigDecimal(10);

            //没有创建过农场
            FarmUser farmUser = FarmUser.builder()
                    .userId(user.getId())
                    .cowLevel(0)
                    .currentMilk(BigDecimal.ZERO)
                    .historyMilk(BigDecimal.ZERO)
                    .grass(gift)
                    .treeLevel(0)
                    .growth(BigDecimal.ZERO)
                    .water(gift)
                    .fertilizer(BigDecimal.ZERO)
                    .status(ToggleEnum.ON.getStatus())
                    .createdAt(new Date())
                    .updatedAt(new Date())
                    .build();
            farmUserMapper.insert(farmUser);

            selectFarmUser = farmUser;

            createInitGrassAndWater(user);
        }

        //没有创建过奶牛
        if (selectCow == null) {
            Cow cow = Cow.builder()
                    .userId(user.getId())
                    .cowMilk(BigDecimal.ZERO)
                    .createdAt(new Date())
                    .updatedAt(new Date())
                    .build();
            cowMapper.insert(cow);
            selectCow = cow;
        }

        //获取未读信件数量
        Date readDate = mailboxReadMapper.selectReadTimeByUserIdAndType(user.getId(), MailBoxTypeEnum.COW.getType());
        if (readDate == null) {
            readDate = new Date(1632308709360L);
        }
        Integer unreadNumber = mailboxMapper.getUnreadNumber(MailBoxTypeEnum.COW.getType(), readDate);
        Cow resultCow = cowMapper.findOneByUserId(user.getId());
        FarmUserVO vo = new FarmUserVO();
        vo.setCow(resultCow);
        vo.setFarmUser(selectFarmUser);
        vo.setUnreadNumber(unreadNumber);
        vo.setCurrentCowMilk(selectCow.getCowMilk());
        return new ResultData<>(vo);
    }


    @Override
    public BaseResp editCow(Cow cow) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Cow selectCow = cowMapper.findOneByUserId(user.getId());
        selectCow.setDecorate(cow.getDecorate());
        cowMapper.updateByPrimaryKeySelective(selectCow);
        return new BaseResp();
    }

    @Override
    public BaseResp eatGrass(BigDecimal grass) {
        String rate = daoService.getHipoConfigValue(HipoConfigEnum.COW_MILK_RATE.getConfig());
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        if (UserStatusEnum.BAN.getStatus().equals(user.getStatus())) {
            return new BaseResp(ResultCode.USER_BAN);
        }

        Cow selectCow = cowMapper.findOneByUserId(user.getId());
        FarmUser selectFarmUser = farmUserMapper.findOneByUserId(user.getId());
        if (selectFarmUser.getGrass().compareTo(grass) == -1) {
            //没有那么多草
            return new BaseResp(ResultCode.NEED_GRASS_NOT_ENOUGH);
        }
        BigDecimal cowMilk = selectCow.getCowMilk().add(grass.multiply(new BigDecimal(rate)));
        BigDecimal addMilk = BigDecimal.ZERO;
        BigDecimal subGrass = BigDecimal.ZERO;
        //如果奶牛身上的牛奶达到1kg  退回多余的草料
        if (cowMilk.compareTo(BigDecimal.ONE) == 1) {
            addMilk = BigDecimal.ONE.subtract(selectCow.getCowMilk());
            subGrass = addMilk.divide(new BigDecimal(rate));
        } else {
            addMilk = grass.multiply(new BigDecimal(rate));
            subGrass = grass;
        }
        //草料转化为牛奶
        if (selectCow != null) {
            Cow cow = Cow.builder()
                    .id(selectCow.getId())
                    .cowMilk(selectCow.getCowMilk().add(addMilk))
                    .eatTime(new Date())
                    .updatedAt(new Date())
                    .build();
            cowMapper.updateByPrimaryKeySelective(cow);
        }
        //减去用户手中的草料并添加当前牛奶量和历史牛奶量
        FarmUser farmUser = FarmUser.builder()
                .id(selectFarmUser.getId())
                .grass(selectFarmUser.getGrass().subtract(subGrass))
                .updatedAt(new Date())
                .build();
        farmUserMapper.updateByPrimaryKeySelective(farmUser);
        //添加草料流水
        GrassFlow grassFlow = GrassFlow.builder()
                .userId(user.getId())
                .amount(subGrass)
                .tradeType(GrassFlowTradeType.EAT_GRASS.getGrassFlowTradeType())
                .type(GrassFlowTradeType.EAT_GRASS.getType())
                .weight(selectFarmUser.getGrass().subtract(subGrass))
                .remark(GrassFlowTradeType.EAT_GRASS.getRemark())
                .createdAt(new Date())
                .build();
        grassFlowMapper.insert(grassFlow);
        return new BaseResp();
    }

    private void createInitGrassAndWater(User user) {
        GrassFlow grassFlow = GrassFlow.builder()
                .userId(user.getId())
                .amount(new BigDecimal(2))
                .tradeType(GrassFlowTradeType.INIT.getGrassFlowTradeType())
                .type(GrassFlowTradeType.INIT.getType())
                .weight(new BigDecimal(2))
                .remark(GrassFlowTradeType.INIT.getRemark())
                .createdAt(new Date())
                .build();
        grassFlowMapper.insert(grassFlow);

        //水能量流水
        WaterFlow waterFlow = WaterFlow.builder()
                .userId(user.getId())
                .amount(new BigDecimal(2))
                .tradeType(WaterFlowTradeType.INIT.getWaterFlowTradeType())
                .type(WaterFlowTradeType.INIT.getType())
                .weight(new BigDecimal(2))
                .remark(WaterFlowTradeType.INIT.getRemark())
                .createdAt(new Date())
                .build();
        waterFlowMapper.insert(waterFlow);
    }

    private Integer getLevel(BigDecimal milk) {
        String cowRank = daoService.getHipoConfigValue(HipoConfigEnum.COW_RANK.getConfig());
        String[] strs = cowRank.split(",");
        for (int i = strs.length - 1; i >= 0; i--) {
            if (milk.compareTo(new BigDecimal(strs[i])) >= 0) {
                return i + 1;
            }
        }
        return 0;
    }

    @Override
    public BaseResp milking(User user) {
        Cow selectCow = cowMapper.findOneByUserId(user.getId());
        FarmUser selectFarmUser = farmUserMapper.findOneByUserId(user.getId());
        if (selectCow != null && selectFarmUser != null) {
            BigDecimal milk = selectCow.getCowMilk();
            //获取挤牛奶后的等级
            Integer level = getLevel(milk.add(selectFarmUser.getHistoryMilk()));
            FarmUser farmUser = FarmUser.builder()
                    .id(selectFarmUser.getId())
                    .cowLevel(level)
                    .currentMilk(selectFarmUser.getCurrentMilk().add(milk))
                    .historyMilk(selectFarmUser.getHistoryMilk().add(milk))
                    .updatedAt(new Date())
                    .build();
            Cow cow = Cow.builder()
                    .id(selectCow.getId())
                    .cowMilk(BigDecimal.ZERO)
                    .updatedAt(new Date())
                    .build();
            farmUserMapper.updateByPrimaryKeySelective(farmUser);
            cowMapper.updateByPrimaryKeySelective(cow);
        }
        return new BaseResp();

    }

    @Override
    public ResultData<List<FarmUserRankVO>> getCowRank(User user) {
        List<FarmUserRankVO> list = farmUserMapper.getCowRank();
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(FarmUserRankVO::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setUserNickname(userMap.get(item.getUserId()).getNickname());
                item.setUserAvatar(userMap.get(item.getUserId()).getAvatar());
            });
        }
        return new ResultData<>(list);
    }

    @Override
    public ResultData<FarmUserVO> getTreeDetail(User user) {
        FarmUser selectFarmUser = farmUserMapper.findOneByUserId(user.getId());
        if (selectFarmUser == null) {

            // 判断是否有人邀请，如果有，则送10kg草料和10kg水能量
            UserRelationship userRelationship = userRelationshipMapper.findOneBySubordinateId(user.getId());
            BigDecimal gift = userRelationship == null ? new BigDecimal(2) : new BigDecimal(10);

            //没有创建过农场
            FarmUser farmUser = FarmUser.builder()
                    .userId(user.getId())
                    .currentMilk(BigDecimal.ZERO)
                    .historyMilk(BigDecimal.ZERO)
                    .cowLevel(0)
                    .treeLevel(0)
                    .grass(gift)
                    .growth(BigDecimal.ZERO)
                    .water(gift)
                    .fertilizer(BigDecimal.ZERO)
                    .status(ToggleEnum.ON.getStatus())
                    .createdAt(new Date())
                    .updatedAt(new Date())
                    .build();
            farmUserMapper.insert(farmUser);
            selectFarmUser = farmUser;
            createInitGrassAndWater(user);
        }

        //获取未读信件数量
        Date readDate = mailboxReadMapper.selectReadTimeByUserIdAndType(user.getId(), MailBoxTypeEnum.TREE.getType());
        if (readDate == null) {
            readDate = new Date(1632308709360L);
        }
        Integer unreadNumber = mailboxMapper.getUnreadNumber(MailBoxTypeEnum.TREE.getType(), readDate);
        FarmUserVO vo = new FarmUserVO();
        vo.setFarmUser(selectFarmUser);
        vo.setUnreadNumber(unreadNumber);
        vo.setTrees(treeMapper.findAllByUserIdAndIsExchange(user.getId(), TreeIsExchangeTypeEnum.NOT_EXCHANGE.getType()));


        // 如果一棵果树都没有，则判断是否有过果树，没有则赠送1棵
        if (vo.getTrees().isEmpty()) {
            List<Tree> trees = treeMapper.findAllByUserId(user.getId());
            if (trees.isEmpty()) {
                addTree(user, 1L);
            }
        }

        vo.setSaplingList(saplingMapper.findAllList());
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<TreeVO> getCurrentTreeDetail() {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Tree selectTree = treeMapper.selectOneByUserIdAndIsActive(user.getId(), ToggleEnum.ON.getStatus());
        TreeVO vo = new TreeVO();
        if (selectTree != null) {
            Sapling selectSapling = saplingMapper.selectByPrimaryKey(selectTree.getSaplingId());
            FarmProduct selectFarmProduct = farmProductMapper.selectByPrimaryKey(selectSapling.getFarmProductId());
            BeanUtils.copyProperties(selectTree, vo);
            vo.setFarmProductName(selectFarmProduct.getName());
            vo.setFarmProductMainImage(selectFarmProduct.getMainImage());
            return new ResultData<>(vo);
        }
        return new ResultData<>();
    }

    @Override
    public BaseResp editTreeIsActive(Long treeId) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        //设置当前用户的所有果树未选中
        treeMapper.updateIsActiveByUserId(ToggleEnum.OFF.getStatus(), user.getId());
        //设置当前用户的果树为已选中
        treeMapper.updateIsActiveByIdAndUserId(ToggleEnum.ON.getStatus(), treeId, user.getId());
        return new BaseResp();
    }

    @Override
    public BaseResp addTree(User user, Long saplingId) {
        //获取当前用户种下未收获果树的数量
        Integer treeNumber = treeMapper.getUserTreeNumber(user.getId());
        if (treeNumber >= LIMIT_TREE_NUMBER) {
            return new BaseResp(ResultCode.MAX_SAPLING);
        }
        //判断是否存在选中的树
        Tree isActiveTree = treeMapper.selectOneByUserIdAndIsActive(user.getId(), ToggleEnum.ON.getStatus());
        Byte isActive;
        if (isActiveTree != null) {
            isActive = ToggleEnum.OFF.getStatus();
        } else {
            isActive = ToggleEnum.ON.getStatus();
        }

        // 判断树苗状态和数量
        Sapling sapling = saplingMapper.selectByPrimaryKey(saplingId);
        if (ToggleEnum.ON.getStatus().equals(sapling.getStatus())) {

            if (sapling.getStock() > 0) {
                sapling.setStock(sapling.getStock() - 1);
                sapling.setSales(sapling.getSales() + 1);
                sapling.setUpdatedAt(new Date());
                saplingMapper.updateByPrimaryKeySelective(sapling);

                Tree tree = Tree.builder()
                        .userId(user.getId())
                        .saplingId(saplingId)
                        .growth(BigDecimal.ZERO)
                        .fertilizer(BigDecimal.ZERO)
                        .status(TreeStatusEnum.SAPLING.getStatus())
                        .isActive(isActive)
                        .createdAt(new Date())
                        .updatedAt(new Date())
                        .isExchange(TreeIsExchangeTypeEnum.NOT_EXCHANGE.getType())
                        .build();
                treeMapper.insert(tree);
            } else {
                return new BaseResp(ResultCode.SAPLING_OUT_OF_STOCK);
            }

        } else {
            return new BaseResp(ResultCode.SAPLING_OFFLINE);
        }

        return new BaseResp();
    }

    @Override
    public BaseResp giveUpTree(Long treeId) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Tree selectTree = treeMapper.selectByPrimaryKey(treeId);
        treeMapper.updateIsExchangeByIdAndUserId(TreeIsExchangeTypeEnum.GIVE_UP.getType(), treeId, user.getId());
        //被放弃的果树为选中状态
        if (ToggleEnum.ON.getStatus().equals(selectTree.getIsActive())) {
            //设置当前用户的所有果树未选中
            treeMapper.updateIsActiveByUserId(ToggleEnum.OFF.getStatus(), user.getId());
            //设置最近创建的树为选中
            Tree findTree = treeMapper.findOneByUserIdAndIsExchange(user.getId(), TreeIsExchangeTypeEnum.NOT_EXCHANGE.getType());
            if (findTree != null) {
                treeMapper.updateIsActiveByIdAndUserId(ToggleEnum.ON.getStatus(), findTree.getId(), user.getId());
            }
        }
        return new BaseResp();
    }

    @Override
    public ResultData<List<Sapling>> getSaplingList(User user) {
        List<Sapling> list = saplingMapper.findAll(ToggleEnum.ON.getStatus());
        return new ResultData<>(list);
    }

    private Byte getTreeLevel(Sapling sapling, BigDecimal growth) {
        List<SaplingFeatureDTO> list = JSON.parseArray(sapling.getFeature(), SaplingFeatureDTO.class);
        if (growth.compareTo(list.get(3).getNeedGrowth()) >= 0) {
            return TreeStatusEnum.HARVEST.getStatus();
        } else if (growth.compareTo(list.get(2).getNeedGrowth()) >= 0) {
            return TreeStatusEnum.FRUIT.getStatus();
        } else if (growth.compareTo(list.get(1).getNeedGrowth()) >= 0) {
            return TreeStatusEnum.BIG_TREE.getStatus();
        } else if (growth.compareTo(list.get(0).getNeedGrowth()) >= 0) {
            return TreeStatusEnum.SMALL_TREE.getStatus();
        } else {
            return TreeStatusEnum.SAPLING.getStatus();
        }
    }

    @Override
    public BaseResp waterTree(Long treeId, BigDecimal water) {
        //获取水成长值比例
        String rate = daoService.getHipoConfigValue(HipoConfigEnum.TREE_GROWTH_RATE.getConfig());
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        if (UserStatusEnum.BAN.getStatus().equals(user.getStatus())) {
            return new BaseResp(ResultCode.USER_BAN);
        }

        Tree selectTree = treeMapper.selectByPrimaryKey(treeId);
        Sapling selectSapling = saplingMapper.selectByPrimaryKey(selectTree.getSaplingId());
        FarmUser selectFarmUser = farmUserMapper.findOneByUserId(user.getId());
        Tree tree = new Tree();
        FarmUser farmUser = new FarmUser();
        //是否为当前用户的树
        if (selectTree.getUserId().equals(user.getId())) {
            if(TreeStatusEnum.HARVEST.getStatus().equals(selectTree.getStatus())){
                return new BaseResp(ResultCode.HARVEST_TREE_NOT_NEED_WATER);
            }
            //用户的水是否充足
            if (selectFarmUser.getWater().compareTo(water) >= 0) {
                //是否有肥料并消耗
                Integer level = 0;
                BigDecimal addGrowth;
                BigDecimal fertilizer = selectTree.getFertilizer();
                BigDecimal currentFertilizer = BigDecimal.ZERO;
                if (!fertilizer.equals(BigDecimal.ZERO)) {
                    if (fertilizer.compareTo(water) == -1) {
                        //肥料比水少
                        addGrowth = fertilizer.add(water.multiply(new BigDecimal(rate)));
                        level = getLevel(selectFarmUser.getGrowth().add(addGrowth));
                    } else {
                        //肥料比水多
                        addGrowth = water.add(water.multiply(new BigDecimal(rate)));
                        level = getLevel(selectFarmUser.getGrowth().add(addGrowth));
                        currentFertilizer = fertilizer.subtract(water);
                    }
                } else {
                    //没有肥料,将水转换为成长值
                    addGrowth = water.multiply(new BigDecimal(rate));
                    level = getLevel(selectFarmUser.getGrowth().add(addGrowth));
                }
                farmUser = FarmUser.builder()
                        .id(selectFarmUser.getId())
                        .treeLevel(level)
                        .growth(selectFarmUser.getGrowth().add(addGrowth))
                        .water(selectFarmUser.getWater().subtract(water))
                        .build();
                tree = Tree.builder()
                        .id(selectTree.getId())
                        .growth(selectTree.getGrowth().add(addGrowth))
                        .fertilizer(currentFertilizer)
                        .waterTime(new Date())
                        .status(getTreeLevel(selectSapling, selectTree.getGrowth().add(addGrowth)))
                        .updatedAt(new Date())
                        .build();
                farmUserMapper.updateByPrimaryKeySelective(farmUser);
                treeMapper.updateByPrimaryKeySelective(tree);

                //水能量流水
                WaterFlow waterFlow = WaterFlow.builder()
                        .userId(user.getId())
                        .amount(water)
                        .tradeType(WaterFlowTradeType.WATER.getWaterFlowTradeType())
                        .type(WaterFlowTradeType.WATER.getType())
                        .weight(selectFarmUser.getWater().subtract(water))
                        .remark(WaterFlowTradeType.WATER.getRemark())
                        .createdAt(new Date())
                        .build();
                waterFlowMapper.insert(waterFlow);
            }else {
                return new BaseResp(ResultCode.NEED_WATER_NOT_ENOUGH);
            }
        }
        return new BaseResp();
    }

    @Override
    public ResultData<List<FarmUserRankVO>> getTreeRank(User user) {
        List<FarmUserRankVO> list = farmUserMapper.getTreeRank();
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, User> userMap = daoService.getUserMap(list.stream().map(FarmUserRankVO::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setUserNickname(userMap.get(item.getUserId()).getNickname());
                item.setUserAvatar(userMap.get(item.getUserId()).getAvatar());
            });
        }
        return new ResultData<>(list);
    }

    @Override
    public BaseResp applyFertilizer(User user, BigDecimal fertilizer, Long treeId) {
        Tree selectTree = treeMapper.selectByPrimaryKey(treeId);
        FarmUser selectFarmUser = farmUserMapper.findOneByUserId(user.getId());
        if (selectTree != null && selectFarmUser != null && selectTree.getUserId().equals(user.getId())) {
            if (selectTree.getUserId().equals(user.getId())) {
                //肥料是否足够
                if (selectFarmUser.getFertilizer().compareTo(fertilizer) >= 0) {
                    Tree tree = Tree.builder()
                            .id(selectTree.getId())
                            .fertilizer(selectFarmUser.getFertilizer().add(fertilizer))
                            .updatedAt(new Date())
                            .build();
                    FarmUser farmUser = FarmUser.builder()
                            .id(selectFarmUser.getId())
                            .fertilizer(selectFarmUser.getFertilizer().subtract(fertilizer))
                            .updatedAt(new Date())
                            .build();
                    treeMapper.updateByPrimaryKeySelective(tree);
                    farmUserMapper.updateByPrimaryKeySelective(farmUser);
                }
            }else {
                return new BaseResp(ResultCode.NEED_FERTILIZER_NOT_ENOUGH);
            }
        }
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<FarmTaskVO>> getFarmTaskPage(PageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        req.setStatus(ToggleEnum.ON.getStatus());
        List<FarmTask> list = farmTaskMapper.findAllPage(req);
        List<FarmTaskVO> VOList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, UserTask> userTaskMap = daoService.getUserTaskMap(list.stream().map(FarmTask::getId).collect(Collectors.toList()), user.getId(), getFirstTime(calendar).getTime());
            list.stream().forEach(item -> {
                FarmTaskVO vo = new FarmTaskVO();
                BeanUtils.copyProperties(item, vo);
                vo.setUserTask(userTaskMap.get(item.getId()));
                VOList.add(vo);
            });
        }
        return PageHelpUtil.buildPage(VOList, page);
    }

    private Date getStartTime() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }


    @Override
    public BaseResp editUserTask(UserTask userTask) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        List<UserTask> userTaskList = userTaskMapper.findAllByUserIdAndTaskIdAndTaskTime(user.getId(), userTask.getTaskId(), getFirstTime(calendar).getTime());
        FarmTask selectFarmTask = farmTaskMapper.selectByPrimaryKey(userTask.getTaskId());
        if (userTaskList.size() > 0) {
            //今天已经领取过了或者是下架任务
            return new BaseResp(ResultCode.TASK_HAS_GOT);
        }
        if (ToggleEnum.OFF.getStatus().equals(selectFarmTask.getStatus())) {
            //今天已经领取过了或者是下架任务
            return new BaseResp(ResultCode.TASK_OFF);
        }


        //任务库存是否足够
        if (selectFarmTask.getStock() > 0) {
            //当前完成数量是否达到限制
            int number = userTaskMapper.getCompleteNumber(user.getId(), userTask.getTaskId(), UserTaskStatusEnum.COMPLETE.getStauts());
            if (number < selectFarmTask.getLimitCount()) {
                //添加到领取
                UserTask result = UserTask.builder()
                        .userId(user.getId())
                        .taskId(userTask.getTaskId())
                        .kind(selectFarmTask.getKind())
                        .status(UserTaskStatusEnum.GET.getStauts())
                        .taskTime(getStartTime())
                        .createdAt(new Date())
                        .updatedAt(new Date())
                        .build();
                userTaskMapper.insert(result);
                //更新库存
                selectFarmTask.setSales(selectFarmTask.getSales() + 1);
                selectFarmTask.setStock(selectFarmTask.getStock() - 1);
                farmTaskMapper.updateByPrimaryKeySelective(selectFarmTask);
                return new BaseResp();
            } else {
                return new BaseResp(ResultCode.TASK_LIMIT);
            }
        } else {
            return new BaseResp(ResultCode.TASK_OUT_OF_STOCK);
        }
    }


}
